package model

import (
	"context"
	"fmt"

	"github.com/Masterminds/squirrel"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

var _ SysUserModel = (*customSysUserModel)(nil)

type (
	// SysUserModel is an interface to be customized, add more methods here,
	// and implement the added methods in customSysUserModel.
	SysUserModel interface {
		sysUserModel
		withSession(session sqlx.Session) SysUserModel
		Page(ctx context.Context, page uint64, limit uint64, account string) (uint32, []*SysUser, error)
		Update(ctx context.Context, data *SysUser) error
		UpdatePassword(ctx context.Context, id int64, password string) error
		UpdateStatus(ctx context.Context, id int64, status int32) error
	}

	customSysUserModel struct {
		*defaultSysUserModel
	}
)

// NewSysUserModel returns a model for the database table.
func NewSysUserModel(conn sqlx.SqlConn) SysUserModel {
	return &customSysUserModel{
		defaultSysUserModel: newSysUserModel(conn),
	}
}

func (m *customSysUserModel) withSession(session sqlx.Session) SysUserModel {
	return NewSysUserModel(sqlx.NewSqlConnFromSession(session))
}

func (m *customSysUserModel) Page(ctx context.Context, page uint64, limit uint64, account string) (uint32, []*SysUser, error) {

	statementBuilder := squirrel.StatementBuilder.Where("user_type = 2")
	// 条件语句
	if len(account) > 0 {
		statementBuilder = squirrel.StatementBuilder.Where(squirrel.Like{"account": "%" + account + "%"})
	}

	//查询列表
	pageSqlBuilder := statementBuilder.Select(sysUserRows).From(m.table).Limit(limit).Offset((page - 1) * limit).OrderBy("id desc")

	query, args, err := pageSqlBuilder.ToSql()
	if err != nil {
		return 0, nil, err
	}
	var resp []*SysUser
	err = m.conn.QueryRowsCtx(ctx, &resp, query, args...)
	if err != nil {
		return 0, nil, err
	}

	//查询总数
	countSqlBuilder := statementBuilder.Select("count(id)").From(m.table)

	queryCount, args, err := countSqlBuilder.ToSql()
	if err != nil {
		return 0, nil, err
	}
	var count uint32

	if err := m.conn.QueryRowCtx(ctx, &count, queryCount, args...); err != nil {
		return 0, nil, err
	}

	return count, resp, nil

}

func (m *customSysUserModel) Update(ctx context.Context, newData *SysUser) error {
	builder := squirrel.Update(m.table).Where("id = ?", newData.Id).SetMap(map[string]interface{}{
		"role_id":  newData.RoleId,
		"phone":    newData.Phone,
		"email":    newData.Email,
		"nickname": newData.Nickname,
		"brief":    newData.Brief,
	})
	query, args, err := builder.ToSql()
	if err != nil {
		return err
	}

	_, err = m.conn.ExecCtx(ctx, query, args...)
	return err
}

func (m *customSysUserModel) UpdatePassword(ctx context.Context, id int64, password string) error {
	query := fmt.Sprintf("update %s set `password` = ? where `id` = ?", m.table)

	if _, err := m.conn.ExecCtx(ctx, query, password, id); err != nil {
		return err
	}

	return nil
}

func (m *customSysUserModel) UpdateStatus(ctx context.Context, id int64, status int32) error {
	query := fmt.Sprintf("update %s set `status` = ? where `id` = ?", m.table)

	if _, err := m.conn.ExecCtx(ctx, query, status, id); err != nil {
		return err
	}

	return nil
}
